#include "Model.h"

#include <ezlogger_headers.hpp>

namespace Crows3D
{
   Model::Model(void)
   {
      EZLOGGERSTREAM << "Model constructor" << std::endl;
      //meshes   = new std::list<Mesh*>();
      //effects  = new std::list<EffectPositionTextureNormal*>();
      //textures = new std::list<Texture*>();

      numSubsets = 0;

      destoryMembers = false;
   }

   Model::~Model(void)
   {
      EZLOGGERSTREAM << "Model destructor" << std::endl;
      //if (destoryMembers)
      {
         for each (Mesh* mesh in meshes)
         {
            delete mesh;
         }

         for each (EffectPositionTextureNormal* effect in effects)
         {
            delete effect;
         }

         for each (Texture* texture in textures)
         {
            delete texture;
         }
      }

      meshes.clear();
      effects.clear();
      textures.clear();

      numSubsets = 0;
      
   }

   //bool Model::LoadTexturedCube(Device *dev)
   //{
   //   destoryMembers = true;

   //   mesh = new Mesh();
   //   effect = new EffectPositionTextureNormal();
   //   texture = new Texture();

   //   if (!mesh->InitializeCube(dev))
   //   {
   //      return false;
   //   }

   //   if (!effect->LoadDefaults(dev))
   //   {
   //      return false;
   //   }

   //   if (!texture->Initialize(dev, L".\\Resources\\Textures\\camo.jpg"))
   //   {
   //      return false;
   //   }

   //   return true;
   //}


   bool Model::AddSubset(Device *dev, Mesh *mesh, EffectPositionTextureNormal* effect, Texture *texture)
   {
      this->meshes.push_back(mesh);
      this->effects.push_back(effect);
      this->textures.push_back(texture);

      numSubsets++;


      EZLOGGERSTREAM << "Adding a subset to model. Total subsets: " << numSubsets << std::endl;

      

      return true;
   }



   void Model::Render(Crows3D::Device *dev, Crows3D::Camera* cam)
   {

      //EZLOGGERSTREAM << "Rendering Model. Total subsets: " << numSubsets << std::endl;

      D3DXMATRIX rotX, rotY, rotZ, rotate, translation, scaling, reflexion;
      D3DXMATRIX world, view, proj;

      // Set up all our matrices
      D3DXMatrixScaling(&scaling, scale.x, scale.y, scale.z);

      D3DXMatrixRotationX(&rotX, rotation.x);
      D3DXMatrixRotationY(&rotY, rotation.y);
      D3DXMatrixRotationZ(&rotZ, rotation.z);

      rotate = rotY*rotZ*rotX;

      D3DXMatrixTranslation(&translation, position.x, position.y, position.z);

      D3DXMatrixIdentity(&reflexion);
      //reflexion._11 = -1;

      world = reflexion*scaling*rotate*translation;

      cam->GetMatrices(view, proj);


      // Get some iterators to our renderable data
      std::list<Mesh*>::iterator                         mesh     = meshes.begin();
      std::list<EffectPositionTextureNormal*>::iterator  effect   = effects.begin();
      std::list<Texture*>::iterator                      texture  = textures.begin();
      
      //(*effect)->Commit(dev, *texture, world, view, proj);

      // Render each subset
      
      for (int i = 0; i < numSubsets; ++i)
      {
         (*effect)->Commit(dev, *texture, world, view, proj);
         (*mesh)->Commit(dev); 
         (*mesh)->Render(dev);
         
         // Increment to the next item
         mesh++;
         effect++;
         texture++;
      }
   }


   void Model::SetPosition(float x,  float y,  float z)
   {
      position = D3DXVECTOR3(x, y, z);
   }


   void Model::SetRotation(float rx, float ry, float rz)
   {
      rotation = D3DXVECTOR3(rx, ry, rz);
   }

   void Model::SetScaling(float sx, float sy, float sz)
   {
      scale = D3DXVECTOR3(sx, sy, sz);
   }
}